home *** CD-ROM | disk | FTP | other *** search
- /*
- * dr.c
- *
- * drawing routines
- */
-
- #include "abc.h"
- #include "quickdraw.h"
- #include "windowMgr.h"
-
- struct shapes
- {
- short kind;
- Rect size;
- short oper;
- };
-
-
- struct shapes shapa[20];
- short shapdx;
- PolyHandle triangle;
- PolyHandle pentagon;
- PolyHandle hexagon;
- PolyHandle pentagram;
- RgnHandle theregion;
- RgnHandle tempregion;
-
- PolyHandle polytemp = 0;
- PolyHandle polycurrent;
- short phpts;
-
-
- /*
- * Quickdraw surround functions.
- * These functions provide a consistent
- * interface (at some loss of generality) to
- * all the quickdraw drawing functions.
- */
-
- /* FRAMING */
-
- fr_poly(startpt,endpt)
- Point startpt, endpt;
- {
- Rect drt;
- Rect srt;
-
- Pt2Rect(startpt,endpt,&drt);
- BlockMove(&(*polycurrent)->polyBBox, &srt,sizeof(Rect));
- BlockMove(*polycurrent,*polytemp,(*polycurrent)->polySize);
- InsetRect(&srt, -1, -1);
- MapPoly(polytemp,&srt, &drt);
- FramePoly(polytemp);
- }
-
- fr_regn(startpt, endpt)
- Point startpt, endpt;
- {
- Rect r, r1;
-
- CopyRgn(theregion,tempregion);
- BlockMove(&(*tempregion)->rgnBBox, &r1,sizeof(Rect));
- InsetRect(&r1,-1,-1);
- Pt2Rect(startpt, endpt,&r);
- MapRgn(tempregion, &r1, &r);
- FrameRgn(tempregion);
- }
-
- fr_line(startpt,endpt)
- Point startpt,endpt;
- {
- MoveTo(startpt.h,startpt.v);
- LineTo(endpt.h,endpt.v);
- }
-
- fr_rect(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- FrameRect(&rt);
- }
-
- fr_oval(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- FrameOval(&rt);
- }
-
- fr_rort(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- FrameRoundRect(&rt,20,20);
- }
-
-
- fr_arc(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
- Rect trt;
- short sa;
- short aa;
-
- Pt2Rect(startpt,endpt,&rt);
- cp_arc(&rt,&trt,&sa,&aa);
- FrameArc (&trt,sa,aa);
- }
-
- /* ERASING */
-
- er_line(startpt,endpt)
- Point startpt,endpt;
- {
- GrafPtr gp;
- Pattern tpat;
-
- GetPort(&gp);
- BlockMove(gp->pnPat,&tpat,8);
- PenPat(gp->bkPat);
- MoveTo(startpt.h,startpt.v);
- LineTo(endpt.h,endpt.v);
- PenPat(&tpat);
- }
-
- er_poly(startpt,endpt)
- Point startpt, endpt;
- {
- Rect drt;
- Rect srt;
-
- Pt2Rect(startpt,endpt,&drt);
- BlockMove(*polycurrent,*polytemp,(*polycurrent)->polySize);
- BlockMove(&(*polycurrent)->polyBBox,&srt,sizeof(Rect));
- InsetRect(&srt, -1, -1);
- MapPoly(polytemp,&srt,&drt);
- ErasePoly(polytemp);
- }
-
- er_regn(startpt, endpt)
- Point startpt, endpt;
- {
- Rect r, r1;
-
- CopyRgn(theregion,tempregion);
- BlockMove(&(*tempregion)->rgnBBox, &r1,sizeof(Rect));
- InsetRect(&r1,-1,-1);
- Pt2Rect(startpt, endpt,&r);
- MapRgn(tempregion, &r1, &r);
- EraseRgn(tempregion);
- }
-
-
- er_rect(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- EraseRect(&rt);
- }
-
- er_oval(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- EraseOval(&rt);
- }
-
- er_rort(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- EraseRoundRect(&rt,20,20);
- }
-
- er_arc(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
- Rect trt;
- short sa;
- short aa;
-
- Pt2Rect(startpt,endpt,&rt);
- cp_arc(&rt,&trt,&sa,&aa);
- EraseArc (&trt,sa,aa);
- }
-
- /* PAINTING */
-
- pt_line(startpt,endpt)
- Point startpt,endpt;
- {
- GrafPtr gp;
- Pattern tpat;
-
- MoveTo(startpt.h,startpt.v);
- LineTo(endpt.h,endpt.v);
- }
-
- pt_poly(startpt,endpt)
- Point startpt, endpt;
- {
- Rect drt;
- Rect srt;
-
- Pt2Rect(startpt,endpt,&drt);
- BlockMove(*polycurrent,*polytemp,(*polycurrent)->polySize);
- BlockMove(&(*polycurrent)->polyBBox,&srt,sizeof(Rect));
- InsetRect(&srt, -1, -1);
- MapPoly(polytemp,&srt,&drt);
- PaintPoly(polytemp);
- }
-
- pt_regn(startpt, endpt)
- Point startpt, endpt;
- {
- Rect r, r1;
-
- CopyRgn(theregion,tempregion);
- BlockMove(&(*tempregion)->rgnBBox, &r1,sizeof(Rect));
- InsetRect(&r1,-1,-1);
- Pt2Rect(startpt, endpt,&r);
- MapRgn(tempregion, &r1, &r);
- PaintRgn(tempregion);
- }
-
- pt_rect(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- PaintRect(&rt);
- }
-
- pt_oval(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- PaintOval(&rt);
- }
-
- pt_rort(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- PaintRoundRect(&rt,20,20);
- }
-
-
- pt_arc(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
- Rect trt;
- short sa;
- short aa;
-
- Pt2Rect(startpt,endpt,&rt);
- cp_arc(&rt,&trt,&sa,&aa);
- PaintArc (&trt,sa,aa);
- }
-
- /* INVERTING */
-
- in_line(startpt,endpt)
- Point startpt,endpt;
- {
- GrafPtr gp;
- short tpnMode;
-
- GetPort(&gp);
- tpnMode = gp->pnMode;
- PenMode(patXor);
- MoveTo(startpt.h,startpt.v);
- LineTo(endpt.h,endpt.v);
- PenMode(tpnMode);
- }
-
- in_rect(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- InvertRect(&rt);
- }
-
- in_poly(startpt,endpt)
- Point startpt, endpt;
- {
- Rect drt;
- Rect srt;
-
- Pt2Rect(startpt,endpt,&drt);
- BlockMove(*polycurrent,*polytemp,(*polycurrent)->polySize);
- srt=(*polytemp)->polyBBox;
- InsetRect(&srt,1,1);
- MapPoly(polytemp,&srt,&drt);
- InvertPoly(polytemp);
- }
-
- in_regn(startpt, endpt)
- Point startpt, endpt;
- {
- Rect r, r1;
-
- CopyRgn(theregion,tempregion);
- BlockMove(&(*tempregion)->rgnBBox, &r1,sizeof(Rect));
- InsetRect(&r1,-1,-1);
- Pt2Rect(startpt, endpt,&r);
- MapRgn(tempregion, &r1, &r);
- InvertRgn(tempregion);
- }
-
- in_oval(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- InvertOval(&rt);
- }
-
- in_rort(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
-
- Pt2Rect(startpt,endpt,&rt);
- InvertRoundRect(&rt,20,20);
- }
-
- in_arc(startpt,endpt)
- Point startpt,endpt;
- {
- Rect rt;
- Rect trt;
- short sa;
- short aa;
-
- Pt2Rect(startpt,endpt,&rt);
- cp_arc(&rt,&trt,&sa,&aa);
- InvertArc (&trt,sa,aa);
- }
-
- /* SURROUND FUNCTION SUPPORT */
-
-
- /* ARC COMPUTATION
- * The arc is fixed at 90 degrees. This
- * function (used in all the arc functions
- * above) computes the correct rectangle,
- * start angle, and arc angle given the
- * input rectangle (and 90 degrees).
- *
- * This makes drawing the arcs consistent
- * with drawing the other shapes.
- */
- cp_arc(irt,ort,startangle,arcangle)
- Rect *irt;
- Rect *ort;
- short *startangle;
- short *arcangle;
- {
- short dh;
- short dv;
- static Point anchor;
-
- dh = irt->right - irt->left;
- dv = irt->bottom - irt->top;
- if (not (dh | dv))
- {
- anchor.v = irt->top;
- anchor.h = irt->left;
- }
- *ort = *irt;
-
- if (irt->left equals anchor.h)
- if (irt->top < anchor.v)
- {
- ort->left -= dh;
- ort->top -= dv;
- *startangle = 180;
- *arcangle = -90;
- }
- else
- {
- ort->left -= dh;
- ort->bottom += dv;
- *startangle = 0;
- *arcangle = 90;
- }
- else
- if (irt->top < anchor.v)
- {
- ort->top -= dv;
- ort->right += dh;
- *startangle = 180;
- *arcangle = 90;
- }
- else
- {
- ort->right += dh;
- ort->bottom += dv;
- *startangle = 0;
- *arcangle = - 90;
- }
- }
-
-
- typedef short (*drfunc)();
-
- drfunc a[][7] =
- {fr_line,fr_rect,fr_oval,fr_rort,fr_arc,fr_poly,fr_regn,
- pt_line,pt_rect,pt_oval,pt_rort,pt_arc,pt_poly,pt_regn,
- er_line,er_rect,er_oval,er_rort,er_arc,er_poly,er_regn,
- in_line,in_rect,in_oval,in_rort,in_arc,in_poly,in_regn};
-
- /* INITIALIZE DRAWING
- * Init all kinds in shape array (not used
- * yet and make polygons
- */
-
- drinit()
- {
- short i;
-
- for (i = 0; i < 20; shapa[i++].kind = 0);
-
- shapdx = 0;
- maketriangle();
- makepentagon();
- makehexagon();
- makepentagram();
- makeregion();
- }
-
- /* SET SHAPE
- * This sets the shape code to use
- * and sets it in the current shape
- * entry (only one is used so far).
- * In the case of polygons, it translates
- * the shape code to the polygon code and
- * sets the polygon to use in the
- * global, polycurrent.
- */
- drshape(code)
- short code;
- {
- switch (code)
- {
- case 6:
- polycurrent = triangle;
- break;
- case 7:
- polycurrent = pentagon;
- code = 6;
- break;
- case 8:
- polycurrent = hexagon;
- code = 6;
- break;
- case 9:
- polycurrent = pentagram;
- code = 6;
- break;
- case 10:
- code = 7;
- break;
- }
- shapa[shapdx].kind = code;
- }
-
- /* SET OPERATION
- * Sets operation in shape array
- * (only one used). Also sets
- * cursor to use.
- */
-
- droper(code)
- short code;
- {
- shapa[shapdx].oper = code;
- CursorToUse(2);
- }
-
- drdraw(w)
- WindowRecord *w;
- {
- Point startpt;
- Point thispt;
- Point endpt;
- Point lastpt;
- Rect thisrt;
- Rect lastrt;
- GrafPtr port;
- drfunc frame;
- drfunc draw;
- short angle;
- short dv,dh;
- Point sp;
- Point tp;
- Point lp;
- short shapx;
- short operx;
- short x;
- short y;
-
- SetPort((GrafPtr)w);
- PenMode(patXor);
- PenPat(gray);
- shapx = shapa[shapdx].kind - 1;
- operx = shapa[shapdx].oper - 1;
- if ((shapx < 0) or (operx < 0))
- return;
- frame = a[0][shapx]; /* get address of frame func */
- draw = a[operx][shapx]; /* get address of shape/oper func */
-
- GetMouse(&startpt);
- x=startpt.h;
- y=startpt.v;
- if (x%2 notequal 0)
- x=x+1;
- if (y%2 notequal 0)
- y=y+1;
- startpt.h=x;
- startpt.v=y;
- lastpt=startpt;
-
- do {
- GetMouse(&endpt);
-
- x=endpt.h;
- y=endpt.v;
- if (x%2 notequal 0)
- x=x+1;
- if (y%2 notequal 0)
- y=y+1;
- endpt.h=x;
- endpt.v=y;
-
- thispt = endpt;
- LocalToGlobal(&endpt);
- if (PtInRgn(endpt,w->contRgn) and
- not EqualPt(thispt,lastpt))
- {
- if (not EqualPt(startpt,lastpt))
- (*frame)(startpt,lastpt);
- (*frame)(startpt,thispt);
- lastpt = thispt;
- }
- }
- while (StillDown());
-
- (*frame)(startpt,thispt);
- PenMode(patCopy);
- PenPat(black);
- (*draw)(startpt,thispt);
- }
-
- /*
- * Make New Shapes
- * These routines define polygons that
- * are available from the menu. Each
- * simply defines a polygon (assigning
- * it to the global variable of the
- * appropriate name).
- * NO ERROR CHECKING IS DONE ON THE
- * MEMORY OPERATIONS.
- */
-
- maketriangle()
- {
- short err;
-
- triangle = OpenPoly();
- MoveTo(20,20);
- Line(20,0);
- Line(-10,-20);
- Line(-10,20);
- ClosePoly();
- setpolytemp((*triangle)->polySize);
- }
-
- makepentagon()
- {
- pentagon = OpenPoly();
- MoveTo(50,0);
- Line(48,35);
- Line(-19,65);
- Line(-58,0);
- Line(-19,-65);
- Line(48,-35);
- ClosePoly();
- setpolytemp((*pentagon)->polySize);
- }
-
- makehexagon()
- {
- hexagon = OpenPoly();
- MoveTo (21,0);
- Line(58,0);
- Line(28,50);
- Line(-28,50);
- Line(-58,0);
- Line(-28,-50);
- Line(28,-50);
- ClosePoly();
- setpolytemp((*hexagon)->polySize);
- }
-
- makepentagram()
- {
- pentagram = OpenPoly();
- MoveTo(50,0);
- Line(30,90);
- Line(-78,-55);
- Line(96,0);
- Line(-78,55);
- Line(30,-90);
- ClosePoly();
- setpolytemp((*pentagram)->polySize);
- }
-
- /* The original of the polygon is not
- * changed when it is scaled and
- * displayed. Instead a copy is used.
- * Since the program has no idea how
- * big a space to reserve for the copy,
- * setpolytemp() adjusts the size
- * reserved for the global handle
- * polytemp.
- * NO ERROR CHECKING IS DONE ON THE
- * MEMORY OPERATIONS.
- */
- setpolytemp(size)
- short size;
- {
- if (polytemp equals 0)
- polytemp = (PolyHandle)NewHandle(size);
- else if (size > GetHandleSize(polytemp))
- SetHandleSize(polytemp,size);
- }
-
- makeregion()
- {
- Point sp,ep;
- Rect r;
-
- sp.h = 10;
- sp.v = 10;
- ep.h = 60;
- ep.v = 60;
- theregion = NewRgn();
- OpenRgn();
- SetRect(&r,0,0,10,60);
- FrameRect(&r);
- SetRect(&r,40,0,50,60);
- FrameRect(&r);
- SetRect(&r,10,25,40,35);
- FrameRect(&r);
- CloseRgn(theregion);
- tempregion = NewRgn();
- }
-